package com.mazaiting.widget.view

import android.annotation.SuppressLint
import android.app.AppOpsManager
import android.content.Context
import android.content.Intent
import android.graphics.PixelFormat
import android.net.Uri
import android.os.Binder
import android.os.Build
import android.provider.Settings
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.WindowManager
import android.widget.ImageView
import androidx.appcompat.app.AppCompatActivity
import com.mazaiting.widget.R


/***
 *
 *
 *                                                    __----~~~~~~~~~~~------___
 *                                   .  .   ~~//====......          __--~ ~~
 *                   -.            \_|//     |||\\  ~~~~~~::::... /~
 *                ___-==_       _-~o~  \/    |||  \\            _/~~-
 *        __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
 *    _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
 *  .~       .~       |   \\ -_    /  /-   /   ||      \   /
 * /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
 * |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
 *          '         ~-|      /|    |-~\~~       __--~~
 *                      |-~~-_/ |    |   ~\_   _-~            /\
 *                           /  \     \__   \/~                \__
 *                       _--~ _/ | .-~~____--~-/                  ~~==.
 *                      ((->/~   '.|||' -_|    ~~-/ ,              . _||
 *                                 -_     ~\      ~~---l__i__i__i--~~_/
 *                                 _-~-__   ~)  \--______________--~~
 *                               //.-~~~-~_--~- |-------~~~~~~~~
 *                                      //.-~~~--\
 *                               神兽保佑
 *                              代码无BUG!
 * @author mazaiting
 * @date 2019-07-30
 * @description 悬浮窗工具类
 */
object FloatView {

    /**
     * 创建悬浮窗
     * @param context 上下文
     * @param onClick 点击事件
     * @return 返回视图
     */
    @SuppressLint("InflateParams")
    fun addFloatView(context: Context, onClick: View.OnClickListener): View? {
        // 获取窗口管理者
        val windowManager: WindowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
        // 设置LayoutParam
        val layoutParams: WindowManager.LayoutParams = WindowManager.LayoutParams()
        // 根据不同平台设置
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
        } else {
            layoutParams.type = WindowManager.LayoutParams.TYPE_PHONE
        }
        // 设置格式
        layoutParams.format = PixelFormat.RGBA_8888
        // 设置位置
        layoutParams.gravity = Gravity.START or Gravity.TOP
        // 不获取焦点
        layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
        // 设置显示坐标
        layoutParams.x = 0
        layoutParams.y = 0
        // 设置宽高
        layoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT
        layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT
        // 加载布局
        val view = LayoutInflater.from(context).inflate(R.layout.float_view, null)
        // 获取悬浮按钮
        val imageView: ImageView = view.findViewById(R.id.imageView)
        // 添加
        windowManager.addView(view, layoutParams)
        // 表示开发人员可以将视图按照自己的意愿设置成任意的大小，没有任何限制
        view.measure(
            View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
            View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
        )
        // 移动事件
        view.setOnTouchListener { _, event ->
            // 设置新的 x
            layoutParams.x = event.rawX.toInt() - imageView.measuredWidth / 2
            // 设置新的 y
            layoutParams.y = event.rawY.toInt() - imageView.measuredHeight / 2 - 25
            // 更新布局
            windowManager.updateViewLayout(view, layoutParams)
            false
        }
        // 设置点击事件
        view.setOnClickListener(onClick)

        return view
    }

    /**
     * 移除悬浮窗
     * @param context 上下文
     * @param view 悬浮窗
     */
    fun removeFloatView(context: Context, view: View) {
        // 获取窗口管理者
        val windowManager: WindowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
        // 移除
        windowManager.removeViewImmediate(view)
    }

    /**
     * 检测悬浮窗权限
     * @param context 上下文
     */
    fun checkFloatPermission(context: Context) : Boolean {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            try {
                var cls = Class.forName("android.content.Context")
                val declaredField = cls.getDeclaredField("APP_OPS_SERVICE")
                declaredField.isAccessible = true
                var obj: Any? = declaredField.get(cls) as? String ?: return false
                val str2 : String = obj as String
                obj = cls.getMethod("getSystemService", String::class.java).invoke(context, str2)
                cls = Class.forName("android.app.AppOpsManager")
                val declaredField2 = cls.getDeclaredField("MODE_ALLOWED")
                declaredField2.isAccessible = true
                val  checkOp = cls.getMethod("checkOp", Integer.TYPE, Integer.TYPE, String::class.java)
                val  result = checkOp.invoke(obj, 24, Binder.getCallingUid(), context.packageName) as Int
                return result == declaredField2.getInt(cls)
            } catch (e: Exception) {
                return false
            }
        } else {
            return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                val appOpsMgr = context.getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager
                val mode = appOpsMgr.checkOpNoThrow("android:system_alert_window",
                    android.os.Process.myUid(), context.packageName)
                mode == AppOpsManager.MODE_ALLOWED || mode == AppOpsManager.MODE_IGNORED
            } else {
                Settings.canDrawOverlays(context)
            }
        }
    }

    /**
     * 开启权限界面
     * @param context 活动
     */
    fun startPermissionActivity(context: AppCompatActivity, requestCode: Int) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            // 开启悬浮窗界面
            context.startActivityForResult(Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:${context.packageName}")), requestCode)
        } else {
            context.startActivityForResult(Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:${context.packageName}")), requestCode)
        }
    }
}